home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 25 / AACD 25.iso / AACD / Magazine / Online / QMail / source / qsmhook.c < prev    next >
Encoding:
C/C++ Source or Header  |  1997-04-15  |  3.4 KB  |  138 lines

  1. #include "fd.h"
  2. #include "stralloc.h"
  3. #include "readwrite.h"
  4. #include "sgetopt.h"
  5. #include "wait.h"
  6. #include "env.h"
  7. #include "byte.h"
  8. #include "str.h"
  9. #include "alloc.h"
  10. #include "exit.h"
  11. #include "fork.h"
  12. #include "case.h"
  13. #include "subfd.h"
  14. #include "error.h"
  15. #include "substdio.h"
  16. #include "sig.h"
  17.  
  18. void die(e,s) int e; char *s; { substdio_putsflush(subfderr,s); _exit(e); }
  19. void die_usage() { die(100,"qsmhook: fatal: incorrect usage\n"); }
  20. void die_temp() { die(111,"qsmhook: fatal: temporary problem\n"); }
  21. void die_read() { die(111,"qsmhook: fatal: unable to read message\n"); }
  22. void die_badcmd() { die(100,"qsmhook: fatal: command not found\n"); }
  23.  
  24. int flagrpline = 0; char *rpline;
  25. int flagufline = 1; char *ufline;
  26. int flagdtline = 0; char *dtline;
  27. char *host;
  28. char *sender;
  29. char *recip;
  30.  
  31. stralloc newarg = {0};
  32.  
  33. substdio ssout;
  34. char outbuf[SUBSTDIO_OUTSIZE];
  35. substdio ssin;
  36. char inbuf[SUBSTDIO_INSIZE];
  37.  
  38. void main(argc,argv)
  39. int argc;
  40. char **argv;
  41. {
  42.  int pid;
  43.  int wstat;
  44.  int pi[2];
  45.  int opt;
  46.  char **arg;
  47.  char *x;
  48.  int i;
  49.  int flagesc;
  50.  
  51.  sig_pipeignore();
  52.  
  53.  if (!(dtline = env_get("DTLINE"))) die_usage();
  54.  if (!(rpline = env_get("RPLINE"))) die_usage();
  55.  if (!(ufline = env_get("UFLINE"))) die_usage();
  56.  if (!(recip = env_get("LOCAL"))) die_usage();
  57.  if (!(host = env_get("HOST"))) die_usage();
  58.  if (!(sender = env_get("SENDER"))) die_usage();
  59.  
  60.  while ((opt = getopt(argc,argv,"DFlMmnPsx:")) != opteof)
  61.    switch(opt)
  62.     {
  63.      case 'D': case 'F': case 'M': break; /* be serious */
  64.      case 'l': flagdtline = 1; break; /* also return-receipt-to? blech */
  65.      case 'm': break; /* we only handle one recipient anyway */
  66.      case 'n': flagufline = 0; break;
  67.      case 's': break; /* could call quote() otherwise, i suppose... */
  68.      case 'P': flagrpline = 1; break;
  69.      case 'x':
  70.        if (case_starts(recip,optarg))
  71.      recip += str_len(optarg);
  72.        break;
  73.      default:
  74.        _exit(100);
  75.     }
  76.  argc -= optind;
  77.  argv += optind;
  78.  
  79.  if (!*argv) die_usage();
  80.  
  81.  for (arg = argv;x = *arg;++arg)
  82.   {
  83.    if (!stralloc_copys(&newarg,"")) die_temp();
  84.    flagesc = 0;
  85.    for (i = 0;x[i];++i)
  86.      if (flagesc)
  87.       {
  88.        switch(x[i])
  89.     {
  90.      case '%': if (!stralloc_cats(&newarg,"%")) die_temp(); break;
  91.      case 'g': if (!stralloc_cats(&newarg,sender)) die_temp(); break;
  92.      case 'h': if (!stralloc_cats(&newarg,host)) die_temp(); break;
  93.      case 'u': if (!stralloc_cats(&newarg,recip)) die_temp(); break;
  94.     }
  95.        flagesc = 0;
  96.       }
  97.      else
  98.        if (x[i] == '%')
  99.      flagesc = 1;
  100.        else
  101.      if (!stralloc_append(&newarg,&x[i])) die_temp();
  102.    if (!stralloc_0(&newarg)) die_temp();
  103.    i = str_len(newarg.s) + 1;
  104.    if (!(x = alloc(i))) die_temp();
  105.    byte_copy(x,i,newarg.s);
  106.    *arg = x;
  107.   }
  108.  
  109.  if (pipe(pi) == -1) die_temp();
  110.  
  111.  switch(pid = fork())
  112.   {
  113.    case -1:
  114.      die_temp();
  115.    case 0:
  116.      close(pi[1]);
  117.      if (fd_move(0,pi[0]) == -1) die_temp();
  118.      sig_pipedefault();
  119.      execvp(*argv,argv);
  120.      if (error_temp(errno)) die_temp();
  121.      die_badcmd();
  122.   }
  123.  close(pi[0]);
  124.  
  125.  substdio_fdbuf(&ssout,write,pi[1],outbuf,sizeof(outbuf));
  126.  substdio_fdbuf(&ssin,read,0,inbuf,sizeof(inbuf));
  127.  if (flagufline) substdio_bputs(&ssout,ufline);
  128.  if (flagrpline) substdio_bputs(&ssout,rpline);
  129.  if (flagdtline) substdio_bputs(&ssout,dtline);
  130.  if (substdio_copy(&ssout,&ssin) == -2) die_read();
  131.  substdio_flush(&ssout);
  132.  close(pi[1]);
  133.  
  134.  if (wait_pid(&wstat,pid) == -1) die_temp();
  135.  if (wait_crashed(wstat)) die_temp();
  136.  _exit(wait_exitcode(wstat));
  137. }
  138.